package com.baidu.ocrgeneralocrdemo;

import android.app.Activity;
import android.graphics.Bitmap;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;

import com.baidu.vis.ocrgeneralocr.Predictor;
import com.baidu.vis.ocrgeneralocr.Response;
import com.baidu.vis.ocrgeneralocr.SDKExceptions;
import com.baidu.vis.unified.license.AndroidLicenser;
import com.baidu.vis.unified.license.BDLicenseActivator;
import com.baidu.vis.unified.license.BDLicenseLocalInfo;

import java.io.IOException;
import java.util.concurrent.locks.ReentrantLock;

import static com.baidu.vis.ocrgeneralocr.Predictor.UIImageOrientation.UIImageOrientationUp;

import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;

interface  PredictorResultListener{
    void ResultListener(String result) throws IOException;
}

public class PredictorWrapper {
    private static final String TAG = "PredictorWrapper";
    private static ReentrantLock lock = new ReentrantLock();
    private static boolean isRunning = false;
//    static PredictorResultListener  listener;

    public static boolean initLicense(Activity activity, TextView textView) {
        // 获取鉴权相关本地设备及应用相关信息
        BDLicenseLocalInfo bdLicenseLocalInfo =
                AndroidLicenser.getInstance().authGetLocalInfo(activity, Predictor.getAlgorithmId());
        Log.d(TAG, "BDLicenseLocalInfo :" + bdLicenseLocalInfo.toString());

        // 使用申请的license-key 及 收钱文件进行本地授权
//        AndroidLicenser.ErrorCode ret = AndroidLicenser.getInstance().authFromFile(activity,
//                "com_baidu_ocrgeneralocrdemo_220_android",
//                "com_baidu_ocrgeneralocrdemo_220_android", false, Predictor.getAlgorithmId());
//        if (ret != AndroidLicenser.ErrorCode.SUCCESS) {
//            Log.e(TAG, "ErrorMsg :" + AndroidLicenser.getInstance().getErrorMsg(Predictor.getAlgorithmId()));
//            setTextViewOnUiThread(activity, textView, "鉴权失败");
//            return false;
//        }
//        setTextViewOnUiThread(activity, textView, "鉴权成功");

        //int ret = BDLicenseActivator.initLicenseOnLine(acticity, licenseID:"xxxx-xxxx-xxxx-xxxx", filename:"", Predictor.getAlgorithmID());
        // 在线自动激活
        //

        //7X75-TZMR-FTT2-XWRN
        int ret = BDLicenseActivator.initLicenseOnLine(activity, "UR2Y-TPXT-X6JE-ECFP",
                "", Predictor.getAlgorithmId());
        if (ret != 0) {
            setTextViewOnUiThread(activity, textView, "鉴权失败");
        } else {
            setTextViewOnUiThread(activity, textView, "鉴权成功");
        }
        return true;
    }

    public static boolean initModel(Activity activity, TextView textView,PredictorResultListener listener) {
        try {
            // 进行模型初始化
            int ret = Predictor.getInstance().initModelFromAssets(activity, "ocrgeneralocr_models", 1);
            if (ret != 0) {
                Log.d(TAG, "initModel error : " + ret);
                //setTextViewOnUiThread(activity, textView, "模型初始化失败");
                listener.ResultListener("模型初始化失败");
                return false;
            } else {
                //setTextViewOnUiThread(activity, textView, "模型初始化成功");
                listener.ResultListener("模型初始化成功");
                return true;
            }

        } catch (Exception e) {
           // setTextViewOnUiThread(activity, textView, "模型初始化失败");

            e.printStackTrace();
            return false;
        }
    }

    public static String testOneImage(Bitmap bitmap) {
        String result = "";
        try {
            Response[] responses = Predictor.getInstance().predict(bitmap, 0);
            if (responses == null || responses.length < 1) {
                // result = " fail 预测失败 response == null || responses.length < 1";
                result = "";
            } else {
                for (Response response : responses) {
                    Log.d(TAG, "response.resultString :" + response.result);
                    result = result
//                            + response.x1 + "\t" + response.y1 + "\t"
//                            + response.x2 + "\t" + response.y2 + "\t"
//                            + response.x3 + "\t" + response.y3 + "\t"
//                            + response.x4 + "\t" + response.y4 + "\t"
                            + response.result + "\n";
                }
            }

        } catch (SDKExceptions.IlleagleLicense e) {
            result = " fail 授权错误";
            e.printStackTrace();
        } catch (SDKExceptions.NotInit e) {
            result = " fail 未初始化";
            e.printStackTrace();
        }
        return result;
    }

    public static boolean asyncTestOneImage(final Activity activity, final Bitmap bitmap,
                                            final ImageView imageView, final TextView textView,final PredictorResultListener listener) {
        if (activity == null || bitmap == null  ) {
            Log.e(TAG, "activity == null || bitmap == null || imageView == null || textView == null");
            return false;
        }

//        setImageViewOnUiThread(activity, bitmap, imageView);

        if (isRunning) {
            return true;
        }

        Thread thread = new Thread() {
            @Override
            public void run() {
                super.run();

                if (isRunning) {
                    return;
                }

                // 可以做多性能测试
                int count = 1;
                long allTime = 0;
                while (count != 0) {
                    count--;

                    String result = null;
                    if (lock.tryLock()) {
                        isRunning = true;
                      //  setTextViewOnUiThread(activity, textView, "");

                        long startTime = System.currentTimeMillis();
                        result = testOneImage(bitmap);
                        allTime += (System.currentTimeMillis() - startTime);
                        Log.w(TAG, "testOneImage: " + allTime + "ms");
                        if (result != "") {
//                            backResultOnUiThread(activity, listener, result);
                            Log.e(TAG, result);
                        }
                        Log.e(TAG, "result"+result);
                        isRunning = false;
//                        if (!result.isEmpty()){
//
//                        }
//
                        try {
                           listener.ResultListener(result);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }


                        lock.unlock();

                    }
                }
                Log.w(TAG, "testOneImage: " + (allTime / 3000) + "ms");
            }

        };
        thread.start();
        return false;
    }

    static int count = 0;
    static long allTime = 0;

    // will block UI thread if called from UI thread
    public static String syncTestOneImage(Activity activity, Bitmap bitmap, ImageView imageView, TextView textView) {
        if (activity == null || bitmap == null || imageView == null || textView == null) {
            Log.e(TAG, "activity == null || bitmap == null || imageView == null || textView == null");
            return "";
        }
        count++;
        long startTime = System.currentTimeMillis();
        String result = testOneImage(bitmap);
        allTime += (System.currentTimeMillis() - startTime);
        Log.w(TAG, "testOneImage: " + count + " :  " + allTime + "ms");
        Log.w(TAG, "testOneImage: " + count + " :  " + (allTime / count) + "ms");

        setImageViewOnUiThread(activity, bitmap, imageView);
        setTextViewOnUiThread(activity, textView, result);
        return result;
    }

    //
    public static String asyncTestRGB(final byte[] bytes,
                                      final int width, final int height,
                                      final Predictor.ImagePixelFormat type) {
        String result = "";
        try {
            Response[] responses = Predictor.getInstance().predict(bytes, width, height,
                    UIImageOrientationUp, type.ordinal(), 0);
            if (responses == null || responses.length < 1) {
                result = "null";
            } else {
                for (Response response : responses) {
                    Log.e(TAG, "response.resultString :" + response.result);
                    result = result
//                            + response.x1 + "\t" + response.y1 + "\t"
//                            + response.x2 + "\t" + response.y2 + "\t"
//                            + response.x3 + "\t" + response.y3 + "\t"
//                            + response.x4 + "\t" + response.y4 + "\t"
                            + response.result + "\n";
                }
            }

        } catch (SDKExceptions.IlleagleLicense e) {
            result = " fail 授权错误";
            e.printStackTrace();
        } catch (SDKExceptions.NotInit e) {
            result = " fail 未初始化";
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    private static void setTextViewOnUiThread(final Activity activity, final TextView textView,
                                              final String status) {
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                textView.setText(status);
            }
        });
    }

    private static void backResultOnUiThread(final Activity activity, final PredictorResultListener listener,
                                              final String result) {
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    listener.ResultListener(result);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private static void setImageViewOnUiThread(final Activity activity, final Bitmap bitmap,
                                               final ImageView imageView) {
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                imageView.setImageBitmap(bitmap);
            }
        });
    }


}
